//utils/EventSourceWrapper.ts
import {EventSourceConfig} from "../type/EventSourceConfig";

export class EventSourceWrapper {
    private eventSource: EventSource | null = null;
    private config: EventSourceConfig;
    private isActive: boolean = false;
    private static instance:EventSourceWrapper=null;
     static getESWrapperInstance():EventSourceWrapper{
        if(!this.instance) {
            this.instance = new EventSourceWrapper({
                url: "/dev-api/chatStream",
                queryParams: {
                    content: "",
                    contentType: "",
                },
                onEnd: (data) => {
                    console.log('Stream ended:', data);
                },
                onError: (err) => {
                    console.log('Error occurred:', err);
                }
            });
        }
        return this.instance;
    }
    getConfig():EventSourceConfig{
        return this.config;
    }
    //Partial 是 TypeScript 中的一个工具类型，用于创建一个新类型，其中所有属性都是可选的。
    setConfig(config: Partial<EventSourceConfig>): void {
        this.config = {
            ...this.config, // 保留原有配置
            ...config,      // 覆盖新配置
            queryParams: {  // 针对嵌套对象特殊处理
                ...this.config?.queryParams,
                ...config?.queryParams
            },
        };
    }

    constructor(options: EventSourceConfig) {
        this.config = {
            withCredentials: false,
            ...options
        };
    }

    private buildUrl(): string {
        const { url, queryParams } = this.config;
        return queryParams
            ? `${url}?${new URLSearchParams(queryParams)}`
            : url;
    }

    connect(): void {
        if (this.isActive) return;
        try {
            this.isActive = true;
            const url = this.buildUrl();

            this.eventSource = new EventSource(url, {
                withCredentials: this.config.withCredentials
            });

            this.eventSource.onopen = (event) => {
                console.log('SSE connection established', event);
            };

            this.eventSource.onmessage = ({ data }) => {
                this.config.onMessage?.(data);
            };
            //解答完一次为什么都会报错

            this.eventSource.onerror = (event) => {
                console.error('SSE connection error:', event);
                this.close();
                this.config.onError?.(new Error('Connection failed'));
            };

            this.eventSource.addEventListener('close', () => {
                this.close();
                console.log("close")
                this.config.onEnd?.("SSE connection close");
            });

        } catch (error) {
            this.close();
            this.config.onError?.(error instanceof Error ? error : new Error('Connection error'));
        }
    }

    close(): void {
        if (this.eventSource) {
            this.eventSource.close();
            this.eventSource = null;
            this.isActive = false;
        }
    }

    // 手动重新连接（如果需要）
    reconnect(): void {
        this.close();
        this.connect();
    }
}
